package com.thuan.db;


import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import pojo.Privilege;
import pojo.UserAccount;


public class UserDAO implements IUserDAO{
	
	private static SessionFactory sessionFactory;	
	
	public static void setSessionFactory(SessionFactory sessionFactory) {
		UserDAO.sessionFactory = sessionFactory;
	}


	@Override
	public List<UserAccount> getUsers() {
		Session session = sessionFactory.openSession();

		List<UserAccount> users = session.createQuery("from UserAccount").list();
		session.beginTransaction().commit();
		session.close();
		
		return users;
	}

	@Override
	public int addUser(String username, String password, String name, int level) {
		if(findUser(username) != null)
			return -1;
		
		Privilege privilege = findPrivilege(level);
		if(privilege == null) return -1;
		
		UserAccount userAccount = new UserAccount(username, password, name, 0, 0, 0, null, privilege);
		Session session = sessionFactory.openSession();
		session.save(userAccount);
		session.beginTransaction().commit();
		session.close();
		
		return 0;
	}

	@Override
	public UserAccount findUser(String username) {
		UserAccount result = null;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from UserAccount where username = :username");
		query.setParameter("username", username);
		List<UserAccount> users = query.list();
		
		if(!users.isEmpty())
			result = (UserAccount) users.get(0);
		
		session.close();
		return result;
	}
	
	@Override
	public Privilege findPrivilege(int level) {
		Privilege result = null;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from Privilege where level = :level");
		query.setParameter("level", level);
		List<Privilege> pivileges = query.list();
		
		if(!pivileges.isEmpty())
			result = (Privilege) pivileges.get(0);
		
		session.close();
		return result;
	}
	
	public void updateScore(String username,int score,int win,int lose ){
		UserAccount result = null;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from UserAccount where username = :username");
		query.setParameter("username", username);
		result = (UserAccount)query.list().get(0);
		
		//session.update(result);
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			result.setScore(score);
			result.setWin(win);
			result.setLose(lose);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			throw new RuntimeException("Could not begin transaction");
		}
		finally{
		session.close();
		}
	}


	@Override
	public boolean updateUserAccount(String username, String password, String name, int score, int win, int lose, Privilege privilege) {
		UserAccount result = null;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from UserAccount where username = :username");
		query.setParameter("username", username);
		result = (UserAccount)query.list().get(0);
		
		if(result == null)
			return false;
		
		//session.update(result);
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			result.setPassword(password);
			result.setName(name);
			result.setScore(score);
			result.setWin(win);
			result.setLose(lose);
			result.setPrivilege(privilege);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			throw new RuntimeException("Could not begin transaction");
			
		}
		finally{
			session.close();
		}
		return true;
	}


	@Override
	public boolean updatePassword(String username, String password) {
		// TODO Auto-generated method stub
		return false;
	}


	@Override
	public void updateSigninTime(String username) {
		UserAccount result = null;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from UserAccount where username = :username");
		query.setParameter("username", username);
		result = (UserAccount)query.list().get(0);
		
		//session.update(result);
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			result.setSigninTime(new Date());
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			throw new RuntimeException("Could not begin transaction");
		}
		finally{
		session.close();
		}
	}


	public boolean login(String username, String password) {
		boolean result = false;
		
		Session session = sessionFactory.openSession();
		
		Query query = session.createQuery("from UserAccount where username = :username and password = :password");
		query.setParameter("username", username);
		query.setParameter("password", password);
		List<UserAccount> users = query.list();
		
		if(!users.isEmpty())
			result = true;
		
		session.close();
		return result;
	}
	
	@Override
	public boolean addUserAccount(String username, String password, String name, int score, int win, int lose, Privilege privilege) {
		if(findUser(username) != null || privilege == null)
			return false;
		
		UserAccount userAccount = new UserAccount(username, password, name, score, win, lose, null, privilege);
		Session session = sessionFactory.openSession();
		session.save(userAccount);
		session.beginTransaction().commit();
		session.close();
		
		return true;
	}
	
	@Override
	public List<UserAccount> listUserAccounts() {
		Session session = sessionFactory.openSession();

		List<UserAccount> useraccounts = session.createQuery("from UserAccount").list();
		session.beginTransaction().commit();
		session.close();
		
		return useraccounts;
	}
	
	@Override
	public List<Privilege> listPrivileges() {
		Session session = sessionFactory.openSession();

		List<Privilege> privileges = session.createQuery("from Privilege").list();
		session.beginTransaction().commit();
		session.close();
		
		return privileges;
	}
	
	public boolean deleteUserAccount(String username) {
		Session session = sessionFactory.openSession();
        try{
            session.getTransaction().begin();
            UserAccount useraccount = (UserAccount) session.get(UserAccount.class, username);
            session.delete(useraccount);
            session.flush();
            session.getTransaction().commit();
            session.close();
        }
        catch(Exception e){
            if(session.getTransaction().isActive()){
                session.getTransaction().rollback();
            }
            e.printStackTrace(System.err);
            return false;
        }
        
        return true;
	}
}

